using System;
using System.Threading.Tasks;

namespace Multiprocessing.Core.Mathematics.Matrices
{
    public class MatrixFactory
    {
        #region Fields

        private static readonly Lazy<MatrixFactory> Lazy = new Lazy<MatrixFactory>(() => new MatrixFactory());
        // private readonly IUnityContainer _matrixContainer;

        #endregion

        #region Properties

        public static MatrixFactory Instance
        {
            get { return Lazy.Value; }
        }

        #endregion

        #region Constructors

        private MatrixFactory()
        {
            // _matrixContainer = new UnityContainer();
            // InitializeContainer();
        }

        #endregion

        #region Methods

        private void InitializeContainer()
        {
            // _matrixContainer.RegisterType<Matrix>();
        }

        public TMatrix Create<TMatrix>(int rowCount, int columnCount) where TMatrix : IMatrix
        {
            return (TMatrix) Activator.CreateInstance(typeof (TMatrix), rowCount, columnCount);
        }

        public TMatrix CreateIdentity<TMatrix>(int size) where TMatrix : IMatrix
        {
            TMatrix identity = this.Create<TMatrix>(size, size);
            Parallel.For(0, size, i => identity[i, i] = 1);
            return identity;
        }

        public TMatrix CreateRandom<TMatrix>(int rowCount, int columnCount)
            where TMatrix : IMatrix
        {
            TMatrix matrix = this.Create<TMatrix>(rowCount, columnCount);
            matrix.RandomFill();
            return matrix;
        }

        #endregion
    }
}
